package org.myspringmvc.web.servlet.mvc.method.annotation;

import jakarta.servlet.http.HttpServletRequest;
import org.myspringmvc.web.bind.annotation.RequestMethod;
import org.myspringmvc.web.constant.SystemConstant;
import org.myspringmvc.web.method.HandlerMethod;
import org.myspringmvc.web.servlet.HandlerExecutionChain;
import org.myspringmvc.web.servlet.HandlerInterceptor;
import org.myspringmvc.web.servlet.HandlerMapping;
import org.myspringmvc.web.servlet.mvc.RequestMappingInfo;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 莫磊
 * @date 2025/8/12
 * @description 处理器映射器，通过前端提交的请求，来映射要执行的HandlerMethod
 */
public class RequestMappingHandlerMapping implements HandlerMapping {
    /**
     * 处理器映射器主要通过map进行映射
     * key: 请求信息
     * value: 处理器方法
     */
    private Map<RequestMappingInfo, HandlerMethod> map;

    public RequestMappingHandlerMapping(HashMap<RequestMappingInfo, HandlerMethod> map) {
        this.map = map;
    }
    @Override
    public HandlerExecutionChain getHandler(HttpServletRequest request) throws Exception {

        // 通过request封装为RequestMappingInfo对象
        RequestMappingInfo requestMappingInfo = new RequestMappingInfo();
        requestMappingInfo.setRequestURI(request.getServletPath());
        requestMappingInfo.setRequestMethod(RequestMethod.getByValue(request.getMethod().toLowerCase()));
        // 根据request请求返回对应的处理器执行链
        // 根据请求路径和请求方式获取对应的处理器方法
        HandlerMethod handlerMethod = this.map.get(requestMappingInfo);
        // 封装为执行链
        HandlerExecutionChain handlerExecutionChain = new HandlerExecutionChain();
        handlerExecutionChain.setHandler(handlerMethod);
        // 获取拦截器
        handlerExecutionChain.setInterceptors((List<HandlerInterceptor>) request.getServletContext().getAttribute(SystemConstant.INTERCEPTORS));

        // 返回执行链
        return handlerExecutionChain;
    }
}
